package org.yate.oa.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.yate.oa.model.HistoryEntity;
import org.yate.oa.model.LoginEntity;
import org.yate.oa.model.MessageEntity;
import org.yate.oa.model.OrgEntity;
import org.yate.oa.model.RelationEntity;
import org.yate.oa.model.RestDayEntity;
import org.yate.oa.model.TaskEntity;
import org.yate.oa.model.UserEntity;
import org.yate.oa.service.IMessageService;
import org.yate.oa.service.imp.HistoryService;
import org.yate.oa.service.imp.MessageService;
import org.yate.oa.service.imp.OrgService;
import org.yate.oa.service.imp.RelationService;
import org.yate.oa.service.imp.RestDayService;
import org.yate.oa.service.imp.TaskService;
import org.yate.oa.service.imp.UserService;
import org.yate.oa.utils.Constants;
import org.yate.oa.utils.LeaveType;
import org.yate.oa.utils.Pagination;
import org.yate.oa.utils.TaskStatus;
import org.yate.oa.utils.TaskType;

import com.alibaba.fastjson.JSONObject;

@WebServlet(urlPatterns = { "/approval/get", "/approval/post", "/approval/put", "/approval/delete" }, asyncSupported = false)
public class approvalController extends BaseServletController {
	final static String HR_EMAIL = "hr@qbao.com";

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setCharacterEncoding("utf-8");
		res.setContentType("text/html; charset=utf-8");
		req.setCharacterEncoding("utf-8");
		String reqType = req.getParameter("type");
		if (reqType.equals("all")) {
			getApprovals(req, res);
		} else if (reqType.equals("get")) {
			getTaskById(req, res);
		} else if (reqType.equals("provalOne")) {
			approvalOne(req, res);
		} else if (reqType.equals("provalMore")) {
			approvalMore(req, res);
		}
	}

	protected void getApprovals(HttpServletRequest req, HttpServletResponse res) throws IOException {
		PrintWriter out = res.getWriter();
		JSONObject json = new JSONObject();
		TaskService taskService = this.springCtx.getBean(TaskService.class);
		String page = req.getParameter("page");
		int pageIndex = 0;
		if (null != page) {
			pageIndex = Integer.parseInt(page);
		}
		String ownerId = ((LoginEntity) req.getSession().getAttribute("user")).getUserId().toString();
		String[] strings = { ownerId };
		Pagination<TaskEntity> data = taskService.getEntitiesBy(pageIndex, 10, "", "", strings);
		json.put("data", data);
		json.put("status", 200);
		out.println(json);
		out.flush();
		out.close();
	}

	/**
	 * 根据任务id查询
	 * 
	 * @param req
	 * @param res
	 * @throws IOException
	 */
	protected void getTaskById(HttpServletRequest req, HttpServletResponse res) throws IOException {
		String id = req.getParameter("id");
		PrintWriter out = res.getWriter();
		JSONObject json = new JSONObject();
		TaskService taskService = this.springCtx.getBean(TaskService.class);
		TaskEntity taskEntity = taskService.getEntity(Integer.parseInt(id));
		json.put("taskEntity", taskEntity);
		json.put("status", 200);
		out.println(json);
		out.flush();
		out.close();
	}

	protected void approvalOne(HttpServletRequest req, HttpServletResponse res) throws IOException {
		PrintWriter out = res.getWriter();
		JSONObject json = new JSONObject();
		String id = req.getParameter("id");
		String result = req.getParameter("result");
		String desc = req.getParameter("desc");
		Integer ownerId = ((LoginEntity) req.getSession().getAttribute("user")).getUserId();
		// 查出自己所在组织
		RelationService relationService = this.springCtx.getBean(RelationService.class);
		RelationEntity relationEntity = new RelationEntity();
		relationEntity.setUserId(ownerId);
		relationEntity = relationService.getEntityBy(relationEntity);

		OrgService orgService = this.springCtx.getBean(OrgService.class);
		OrgEntity orgEntity = orgService.getEntity(relationEntity.getOrgId());
		orgEntity = orgService.getEntity(orgEntity.getParentOrgId());

		TaskService taskService = this.springCtx.getBean(TaskService.class);
		boolean bol = false;
		TaskEntity taskEntity = taskService.getEntity(Integer.parseInt(id));
		if ("1".equals(result)) {
			Double surplusDay = 0.0;
			if (taskEntity.getTaskType().equals(TaskType.workovertime.name())) {
				surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime()) / Constants.ONE_DAY);
			} else {
				surplusDay = (double) taskEntity.getDays();
			}
			boolean isHR = ((LoginEntity) req.getSession().getAttribute("user")).getEmail().toLowerCase().equals(HR_EMAIL.toLowerCase());
			if (isHR) {
				bol = addHistorRecord(ownerId, Integer.parseInt(id), desc, TaskStatus.completed.name(), taskEntity, true);
				if (bol) {
					taskService.remove(Integer.parseInt(id));
					sendSystemMsg(taskEntity.getUserEntity().getId(), taskEntity, "2");
					json.put("status", 200);
				} else {
					json.put("status", 201);
					json.put("text", "申请调休时间大于剩余调休时间");
				}
			} else {
				addHistorRecord(ownerId, Integer.parseInt(id), desc, TaskStatus.processing.name(), taskEntity, false);
				if (orgEntity != null && orgEntity.getManagerId() != null && (taskEntity.getTaskType().equals(TaskType.workovertime.name()) || surplusDay > 1)) {
					sendSystemMsg(orgEntity.getManagerId(), taskEntity, "1");
					taskEntity = new TaskEntity();
					taskEntity.setLastApprovalId(ownerId);
					taskEntity.setNextApprovalId(orgEntity.getManagerId());
					taskEntity.setId(Integer.parseInt(id));
					taskEntity.setStatus(TaskStatus.processing.name());
					taskService.update(taskEntity);
					json.put("status", 200);
				} else {
					UserService userService = this.springCtx.getBean(UserService.class);
					UserEntity u = new UserEntity();
					u.setEmail(HR_EMAIL.toLowerCase());
					List<UserEntity> list = userService.getEntityBy(u);
					if (list != null && list.size() == 1) {
						sendSystemMsg(list.get(0).getId(), taskEntity, "1");
						taskEntity = new TaskEntity();
						taskEntity.setLastApprovalId(ownerId);
						taskEntity.setNextApprovalId(list.get(0).getId());
						taskEntity.setId(Integer.parseInt(id));
						taskEntity.setStatus(TaskStatus.processing.name());
						taskService.update(taskEntity);
						json.put("status", 200);
					}
				}

			}

		} else {
			bol = addHistorRecord(ownerId, Integer.parseInt(id), desc, TaskStatus.refused.name(), taskEntity, false);
			if (bol) {
				taskService.remove(Integer.parseInt(id));
				sendSystemMsg(taskEntity.getUserEntity().getId(), taskEntity, "0");
			}
			json.put("status", 200);
		}
		out.println(json);
		out.flush();
		out.close();
	}

	protected void approvalMore(HttpServletRequest req, HttpServletResponse res) throws IOException {
		PrintWriter out = res.getWriter();
		JSONObject json = new JSONObject();
		String[] ids = req.getParameter("ids").split(",");
		String result = req.getParameter("result");
		Integer ownerId = ((LoginEntity) req.getSession().getAttribute("user")).getUserId();
		// 查出自己所在组织
		RelationService relationService = this.springCtx.getBean(RelationService.class);
		RelationEntity relationEntity = new RelationEntity();
		relationEntity.setUserId(ownerId);
		relationEntity = relationService.getEntityBy(relationEntity);

		OrgService orgService = this.springCtx.getBean(OrgService.class);
		OrgEntity orgEntity = orgService.getEntity(relationEntity.getOrgId());
		orgEntity = orgService.getEntity(orgEntity.getParentOrgId());
		boolean bol = false;
		TaskService taskService = this.springCtx.getBean(TaskService.class);
		TaskEntity taskEntity = null;
		if ("1".equals(result)) {
			boolean isHR = ((LoginEntity) req.getSession().getAttribute("user")).getEmail().toLowerCase().equals(HR_EMAIL.toLowerCase());
			if (isHR) {
				Date d1140 = null;
				Date d1300 = null;
				Double surplusDay = 0.0;
				for (int i = 0; i < ids.length; i++) {
					taskEntity = taskService.getEntity(Integer.parseInt(ids[i]));
					d1140 = new Date(taskEntity.getBeginDate().getYear(), taskEntity.getBeginDate().getMonth(), taskEntity.getBeginDate().getDate(), 11, 40, 0);
					d1300 = new Date(taskEntity.getBeginDate().getYear(), taskEntity.getBeginDate().getMonth(), taskEntity.getBeginDate().getDate(), 13, 0, 0);
					if (taskEntity.getTaskType().equals(TaskType.workovertime.name())) {
						if (taskEntity.getIsKF() == 0 && taskEntity.getBeginDate().before(d1140) && taskEntity.getEndDate().after(d1300)) {
							// 除去中午午休时间 11:40——13:00
							surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime() - 4800000) / Constants.ONE_DAY);
						} else if (taskEntity.getIsKF() == 1) {
							surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime()) / Constants.KF_ONE_DAY);
						} else {
							surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime()) / Constants.ONE_DAY);
						}
						taskEntity.setDays(surplusDay.floatValue());
					}
					bol = addHistorRecord(ownerId, Integer.parseInt(ids[i]), "同意", TaskStatus.completed.name(), taskEntity, true);
					if (bol) {
						taskService.remove(Integer.parseInt(ids[i]));
						sendSystemMsg(taskEntity.getUserEntity().getId(), taskEntity, "2");
					}
				}
			} else {
				UserService userService = this.springCtx.getBean(UserService.class);
				UserEntity u = new UserEntity();
				u.setEmail(HR_EMAIL.toLowerCase());
				List<UserEntity> list = userService.getEntityBy(u);
				if (orgEntity != null && orgEntity.getManagerId() != null) {
					Double surplusDay = 0.0;
					Date d1140 = null;
					Date d1300 = null;
					for (int i = 0; i < ids.length; i++) {
						taskEntity = taskService.getEntity(Integer.parseInt(ids[i]));
						d1140 = new Date(taskEntity.getBeginDate().getYear(), taskEntity.getBeginDate().getMonth(), taskEntity.getBeginDate().getDate(), 11, 40, 0);
						d1300 = new Date(taskEntity.getBeginDate().getYear(), taskEntity.getBeginDate().getMonth(), taskEntity.getBeginDate().getDate(), 13, 0, 0);
						if (taskEntity.getTaskType().equals(TaskType.workovertime.name())) {
							if (taskEntity.getIsKF() == 0 && taskEntity.getBeginDate().before(d1140) && taskEntity.getEndDate().after(d1300)) {
								// 除去中午午休时间 11:40——13:00
								surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime() - 4800000) / Constants.ONE_DAY);
							} else if (taskEntity.getIsKF() == 1) {
								surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime()) / Constants.KF_ONE_DAY);
							} else {
								surplusDay = ((double) (taskEntity.getEndDate().getTime() - taskEntity.getBeginDate().getTime()) / Constants.ONE_DAY);
							}

						} else {
							surplusDay = (double) taskEntity.getDays();
						}
						if (taskEntity.getTaskType().equals(TaskType.workovertime.name()) || surplusDay > 1) {
							addHistorRecord(ownerId, Integer.parseInt(ids[i]), "同意", TaskStatus.processing.name(), taskEntity, false);
							sendSystemMsg(orgEntity.getManagerId(), taskEntity, "1");
							taskEntity = new TaskEntity();
							taskEntity.setDays(surplusDay.floatValue());
							taskEntity.setLastApprovalId(ownerId);
							taskEntity.setNextApprovalId(orgEntity.getManagerId());
							taskEntity.setId(Integer.parseInt(ids[i]));
							taskEntity.setStatus(TaskStatus.processing.name());
							taskService.update(taskEntity);
						} else {
							if (list != null && list.size() == 1) {
								addHistorRecord(ownerId, Integer.parseInt(ids[i]), "同意", TaskStatus.processing.name(), taskEntity, false);
								sendSystemMsg(list.get(0).getId(), taskEntity, "1");
								taskEntity = new TaskEntity();
								taskEntity.setLastApprovalId(ownerId);
								taskEntity.setNextApprovalId(list.get(0).getId());
								taskEntity.setId(Integer.parseInt(ids[i]));
								taskEntity.setStatus(TaskStatus.processing.name());
								taskService.update(taskEntity);
							}
						}
					}
				} else {
					if (list != null && list.size() == 1) {
						for (int i = 0; i < ids.length; i++) {
							taskEntity = taskService.getEntity(Integer.parseInt(ids[i]));
							addHistorRecord(ownerId, Integer.parseInt(ids[i]), "同意", TaskStatus.processing.name(), taskEntity, false);
							sendSystemMsg(list.get(0).getId(), taskEntity, "1");
							taskEntity = new TaskEntity();
							taskEntity.setLastApprovalId(ownerId);
							taskEntity.setNextApprovalId(list.get(0).getId());
							taskEntity.setId(Integer.parseInt(ids[i]));
							taskEntity.setStatus(TaskStatus.processing.name());
							taskService.update(taskEntity);
						}
					}
				}
			}
		} else {
			for (int i = 0; i < ids.length; i++) {
				taskEntity = taskService.getEntity(Integer.parseInt(ids[i]));
				bol = addHistorRecord(ownerId, Integer.parseInt(ids[i]), "拒绝", TaskStatus.refused.name(), taskEntity, false);
				if (bol) {
					taskService.remove(Integer.parseInt(ids[i]));
					sendSystemMsg(taskEntity.getUserEntity().getId(), taskEntity, "0");
				}
			}
		}
		json.put("status", 200);
		out.println(json);
		out.flush();
		out.close();
	}

	protected boolean addHistorRecord(Integer ownerId, Integer id, String desc, String status, TaskEntity taskEntity, boolean isOver) {

		boolean bol = false;
		if (TaskType.paidleave.name().equals(taskEntity.getTaskType()) && isOver) {
			bol = calculateRestDay(taskEntity, taskEntity.getTaskType());
			if (!bol) {
				return false;
			}
		} else if (TaskType.workovertime.name().equals(taskEntity.getTaskType()) && isOver) {
			bol = calculateRestDay(taskEntity, taskEntity.getTaskType());
			if (!bol) {
				return false;
			}
		} else if (TaskType.leave.name().equals(taskEntity.getTaskType()) && LeaveType.annual.name().equals(taskEntity.getLeaveType()) && isOver) {
			bol = calculateRestDay(taskEntity, taskEntity.getTaskType());
			if (!bol) {
				return false;
			}
		}

		HistoryService historyService = this.springCtx.getBean(HistoryService.class);
		HistoryEntity historyEntity = new HistoryEntity();
		historyEntity.setTaskId(taskEntity.getId());
		historyEntity.setIsComplete(0);
		historyEntity.setStatus(TaskStatus.completed.name());
		historyService.update(historyEntity);

		historyEntity = new HistoryEntity();
		historyEntity.setCreater(taskEntity.getUserEntity());
		historyEntity.setTaskType(taskEntity.getTaskType());
		historyEntity.setMakeDate(taskEntity.getCreationDate());
		historyEntity.setBeginDate(taskEntity.getBeginDate());
		historyEntity.setDays(taskEntity.getDays());
		historyEntity.setEndDate(taskEntity.getEndDate());
		historyEntity.setStatus(status);
		historyEntity.setRemark(taskEntity.getRemark());
		historyEntity.setIsKF(taskEntity.getIsKF());
		UserEntity userEntity = new UserEntity();
		userEntity.setId(ownerId);
		historyEntity.setApprover(userEntity);
		historyEntity.setConclusion(desc);
		historyEntity.setAvaliable(1);
		historyEntity.setTaskId(taskEntity.getId());
		historyEntity.setIsComplete(1);
		historyEntity.setLeaveType(taskEntity.getLeaveType());
		historyService.add(historyEntity);
		return true;
	}

	protected boolean calculateRestDay(TaskEntity taskEntity, String taskType) {
		// 结算剩余调休天数
		RestDayService restDayService = this.springCtx.getBean(RestDayService.class);
		RestDayEntity restDayEntity = restDayService.getEntity(taskEntity.getUserEntity().getId());
		double restDay = restDayEntity.getRestDay();
		double leaveDay = restDayEntity.getLeaveDay();
		Double surplusDay = 0.0;
		if (TaskType.workovertime.name().equals(taskEntity.getTaskType())) {
			// surplusDay = (double) ((taskEntity.getEndDate().getTime() -
			// taskEntity.getBeginDate().getTime()) / Constants.ONE_DAY);
			surplusDay = taskEntity.getDays().doubleValue();
			restDay = restDay + surplusDay;
		} else if (TaskType.paidleave.name().equals(taskEntity.getTaskType())) {
			// 调休
			surplusDay = (double) taskEntity.getDays();
			if (restDay >= surplusDay) {
				restDay = restDay - surplusDay;
			} else {
				return false;
			}
		} else if (TaskType.leave.name().equals(taskEntity.getTaskType())) {
			// 年假
			surplusDay = (double) taskEntity.getDays();
			if (leaveDay >= surplusDay) {
				leaveDay = leaveDay - surplusDay;
			} else {
				return false;
			}
		}
		restDayEntity = new RestDayEntity();
		// restDayEntity.setUserId(taskEntity.getUserEntity().getId());
		restDayEntity.setUserEntity(taskEntity.getUserEntity());
		restDayEntity.setRestDay(restDay);
		restDayEntity.setLeaveDay(leaveDay);
		restDayService.update(restDayEntity);
		return true;
	}

	protected void sendSystemMsg(Integer targetUserId, TaskEntity taskEntity, String type) {
		String taskName = "";
		if (taskEntity.getTaskType().equals(TaskType.leave.name())) {
			taskName = "请假";
		} else if (taskEntity.getTaskType().equals(TaskType.paidleave.name())) {
			taskName = "调休";
		} else if (taskEntity.getTaskType().equals(TaskType.workovertime.name())) {
			taskName = "加班";
		}
		IMessageService msvr = this.springCtx.getBean(MessageService.class);
		String body = "";
		if (type.equals("0")) {
			body = "您的" + taskName + "申请被拒绝。";
		} else if (type.equals("1")) {
			body = taskEntity.getUserEntity().getTrueName() + "发起了" + taskName + "申请。";
		} else if (type.equals("2")) {
			body = "您的" + taskName + "申请已通过审批。";
		}
		MessageEntity me = new MessageEntity(0, targetUserId, body, 0);
		msvr.add(me);
	}
}